package cn.wolfcode.rbac.controller;
// 需求： 要求请求路径为 /permission/list

import cn.wolfcode.rbac.anno.RequiredPermission;
import cn.wolfcode.rbac.domain.Permission;
import cn.wolfcode.rbac.qo.JsonResult;
import cn.wolfcode.rbac.qo.QueryObject;
import cn.wolfcode.rbac.service.IPermissionService;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.lang.reflect.Method;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

@Controller
@RequestMapping("/permission")
public class PermissionController {

    @Autowired
    private IPermissionService permissionService;

    @RequestMapping("/list")
    public String list(Model model, QueryObject qo){
        PageInfo<Permission> pageInfo = permissionService.query(qo);
        model.addAttribute("pageInfo", pageInfo);
        return "permission/list";
    }

    /**
     * 获取字节码对象使用区别：
     * 1.class.forName("类的全限定名")：适合类的的位置是固定
     * 2.对象.getClass()：能拿到对象，就可以获取类的字节码
     * 3.类型.class(): 适用特定的类型的类获取字节码
     */

    @Autowired
    public void setPermissionService(IPermissionService permissionService) {
        this.permissionService = permissionService;
    }

    // 重新加载（自动录入）
    @Autowired
    private ApplicationContext ctx;


    @RequestMapping("/load")
    @ResponseBody // 将java对象转化成为json格式字符串
    public JsonResult load(){
       try {// 先从数据库查询所有的权限
        List<Permission> permissions = permissionService.listAll();

        // 用来存要存的数据库的权限
        Set<Permission> permissionSet = new LinkedHashSet<>();

        // 从Spring 容器获取所有控制器对象，以后加入控制器也不用修改这里的代码
        Collection<Object> ControllerObjects = ctx.getBeansWithAnnotation(Controller.class).values();

        for (Object controllerObject : ControllerObjects) {
            // 获取控制器字节码对象
            // 遍历获取每个控制器独享的字节码
            Class<?> clz = controllerObject.getClass();
            // 获取控制器中所有的处理方法 Method 对象
            Method[] methods = clz.getDeclaredMethods();

            // 遍历控制器中所有方法
            for (Method method : methods) {
                RequiredPermission annotation = method.getAnnotation(RequiredPermission.class);
                if (annotation !=null) {
                    String name = annotation.name();
                    String expression = annotation.expression();
                    /*System.out.println("name = " + name);
                    System.out.println("expression = " + expression);*/


                    // 封装数据
                    Permission permission = new Permission();
                    permission.setExpression(expression);
                    permission.setName(name);

                    // 利用Set 去重
                    // 判断集合中有没有这元素，数据库若不存在这个权限，则在set集合中
                    if (!permissions.contains(permission)) {
                        permissionSet.add(permission);
                    }
                }
            }

        }
        // 在把 Set中的permission 对象中数据存到数据库中，批量保存
        if (permissionSet.size()>0) {
            permissionService.batchSave(permissionSet);
        }
       }catch (Exception e){
           return new JsonResult("权限加载失败",false);
       }
        return new JsonResult("权限加载成功",true);

    }

    // 没有权限返回提示界面

    @RequestMapping("/noPermission")
    public String noPermission(){
        return "common/nopermission";
    }
}
